package com.zhuanzhuan.hero.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bj58.youpin.common.utils.json.JsonUtils;
import com.zhuanzhuan.hero.user.consts.NumConsts;
import com.zhuanzhuan.hero.user.dto.auth.CommitAuthDTO;
import com.zhuanzhuan.hero.user.dto.backend.AuditOperateDTO;
import com.zhuanzhuan.hero.user.entity.HeroUserAudit;
import com.zhuanzhuan.hero.user.entity.HeroUserAuthentication;
import com.zhuanzhuan.hero.user.enums.AuditStateEnum;
import com.zhuanzhuan.hero.user.enums.ExceptionMsgEnum;
import com.zhuanzhuan.hero.user.enums.StateEnum;
import com.zhuanzhuan.hero.user.enums.UserAuthTypeEnum;
import com.zhuanzhuan.hero.user.exception.BusinessException;
import com.zhuanzhuan.hero.user.helper.PushHelper;
import com.zhuanzhuan.hero.user.mapper.HeroUserAuditMapper;
import com.zhuanzhuan.hero.user.pojo.bo.QueryAuditParam;
import com.zhuanzhuan.hero.user.service.HeroUserAuditService;
import com.zhuanzhuan.hero.user.service.HeroUserAuthenticationService;
import com.zhuanzhuan.hero.user.service.IPushService;
import com.zhuanzhuan.hero.user.util.Assert;
import com.zhuanzhuan.hero.user.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * dal Interface:HeroUserAudit
 * @author hanjunjun
 * @date 2024-6-27
 */
@Service
@Slf4j
public class HeroUserAuditServiceImpl extends ServiceImpl<HeroUserAuditMapper, HeroUserAudit>
    implements HeroUserAuditService {

    @Resource
    private HeroUserAuthenticationService userAuthenticationService;

    @Resource
    private IPushService pushService;

    @Override
    public List<HeroUserAudit> listByUid(Long uid) {
        HeroUserAudit query = new HeroUserAudit();
        query.setApplyUid(uid);
        query.setState(StateEnum.EFFECTIVE.getCode());
        return getBaseMapper().select(query);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createAudit(Long uid, CommitAuthDTO commitAuthDTO) {
        log.info("createAudit uid={} param={}", uid, JsonUtils.toJsonWithoutNull(commitAuthDTO));
        Integer authType = commitAuthDTO.getAuthType();
        HeroUserAudit userAudit = this.getByUidAndAuthType(uid, authType);
        if (Objects.isNull(userAudit)) {
            log.info("不存在提交记录，保存");
            this.save(this.buildEntity(uid, authType, commitAuthDTO.getAuditPics(), commitAuthDTO.getPrivacyPics(),
                commitAuthDTO.getBindMobile()));
        } else if (AuditStateEnum.WAIT_AUDIT.getCode().equals(userAudit.getAuditStatus())) {
            log.info("审核中,不可重复提交");
            throw new BusinessException("努力审核中，请稍后");
        } else if (AuditStateEnum.PASS.getCode().equals(userAudit.getAuditStatus())) {
            if (UserAuthTypeEnum.DOUYIN_V.getCode().equals(authType)) {
                //抖音大v 可进阶审核
                log.info("审核通过，进阶审核");
                //删除旧的  创建新的
                this.delById(userAudit.getId());
                this.save(this.buildEntity(uid, authType, commitAuthDTO.getAuditPics(), commitAuthDTO.getPrivacyPics(),
                    commitAuthDTO.getBindMobile()));
            } else {
                log.info("审核已通过，不可重复提交");
                throw new BusinessException("审核已通过，不可重复提交");
            }
        } else if (AuditStateEnum.REJECT.getCode().equals(userAudit.getAuditStatus())) {
            log.info("审核驳回，删除旧记录创建新记录");
            this.delById(userAudit.getId());
            this.save(this.buildEntity(uid, authType, commitAuthDTO.getAuditPics(), commitAuthDTO.getPrivacyPics(), commitAuthDTO.getBindMobile()));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void passAudit(AuditOperateDTO auditOperateDTO) {
        //查询
        HeroUserAudit userAudit = this.getById(auditOperateDTO.getAuditId());
        Assert.notNull(userAudit, ExceptionMsgEnum.BUSINESS_ERROR);

        Long operaterUid = auditOperateDTO.getOperaterUid();
        Integer authType = userAudit.getAuditType();

        HeroUserAudit update = new HeroUserAudit();
        update.setAuditUid(operaterUid);
        update.setAuditTime(auditOperateDTO.getOperateTime());
        update.setAuditStatus(AuditStateEnum.PASS.getCode());
        update.setUpdateBy(operaterUid);
        if (UserAuthTypeEnum.DOUYIN_V.getCode().equals(authType)) {
            String douyinLevel = auditOperateDTO.getDouyinLevel();
            if (StringUtils.isBlank(douyinLevel)) {
                throw new BusinessException("douyinLevel不可为空");
            }
            update.setVerifiedLevel(douyinLevel);
        }
        update.setId(auditOperateDTO.getAuditId());
        this.updateById(update);

        //更新认证信息
        HeroUserAuthentication userAuthUpdate = new HeroUserAuthentication();
        userAuthUpdate.setUpdateBy(NumConsts.SYSTEM_CODE);
        //赋值更新字段
        if (UserAuthTypeEnum.STORE.getCode().equals(authType)) {
            userAuthUpdate.setIsStoreAuth(NumConsts.ONE);
        } else if (UserAuthTypeEnum.RECYCER.getCode().equals(authType)) {
            userAuthUpdate.setIsRecyclerAuth(NumConsts.ONE);
        } else if (UserAuthTypeEnum.E_MERCHANT.getCode().equals(authType)) {
            userAuthUpdate.setIsEMerchantAuth(NumConsts.ONE);
        } else if (UserAuthTypeEnum.LARGE_GOODS.getCode().equals(authType)) {
            userAuthUpdate.setIsLargeGoodsAuth(NumConsts.ONE);
        } else if (UserAuthTypeEnum.DOUYIN_TALENT.getCode().equals(authType)) {
            userAuthUpdate.setIsDouyinTalent(NumConsts.ONE);
        } else if (UserAuthTypeEnum.DOUYIN_V.getCode().equals(authType)) {
            userAuthUpdate.setIsDouyinVAuth(NumConsts.ONE);
            userAuthUpdate.setDouyinVLabel(auditOperateDTO.getDouyinLevel());
        }
        userAuthenticationService.updateByUid(userAudit.getApplyUid(), userAuthUpdate);

        //发送push
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("auditTypeName", UserAuthTypeEnum.getNameByCode(userAudit.getAuditType()));
        pushService.sendPushAsync(userAudit.getApplyUid(), PushHelper.AUDIT_PASS_TEMPLATE_ID, paramMap);
    }

    @Override
    public void rejectAudit(AuditOperateDTO auditOperateDTO) {
        HeroUserAudit dbRecord = this.queryById(auditOperateDTO.getAuditId());
        Assert.notNull(dbRecord, ExceptionMsgEnum.DATA_NOT_EXIST);

        Long operaterUid = auditOperateDTO.getOperaterUid();
        HeroUserAudit update = new HeroUserAudit();
        update.setAuditUid(operaterUid);
        update.setAuditTime(auditOperateDTO.getOperateTime());
        update.setAuditStatus(AuditStateEnum.REJECT.getCode());
        update.setRejectReason(auditOperateDTO.getAuditRemark());
        update.setUpdateBy(operaterUid);
        update.setId(auditOperateDTO.getAuditId());
        this.updateById(update);

        //发push
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("auditTypeName", UserAuthTypeEnum.getNameByCode(dbRecord.getAuditType()));
        paramMap.put("rejectReason", auditOperateDTO.getAuditRemark());
        pushService.sendPushAsync(dbRecord.getApplyUid(), PushHelper.AUDIT_REJECT_TEMPLATE_ID, paramMap);
    }

    @Override
    public HeroUserAudit getByUidAndAuthType(Long uid, Integer auditType) {
        HeroUserAudit query = new HeroUserAudit();
        query.setApplyUid(uid);
        query.setAuditType(auditType);
        query.setState(StateEnum.EFFECTIVE.getCode());

        List<HeroUserAudit> list = getBaseMapper().select(query);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }

        return list.get(NumConsts.ZERO);
    }

    @Override
    public void delById(Long id) {
        log.info("deleteUserAudit id={}", id);
        HeroUserAudit update = new HeroUserAudit();
        update.setId(id);
        update.setState(StateEnum.IS_DELETED.getCode());
        this.updateById(update);
    }

    @Override
    public HeroUserAudit queryById(Long id) {
        LambdaQueryWrapper<HeroUserAudit> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HeroUserAudit::getId, id)
            .eq(HeroUserAudit::getState, StateEnum.EFFECTIVE.getCode());
        return this.getOne(queryWrapper);
    }

    @Override
    public List<HeroUserAudit> listByParam(QueryAuditParam queryAuditParam) {
        log.info("listByParam queryAuditParam={}", JsonUtils.toJsonWithoutNull(queryAuditParam));
        return this.getBaseMapper().listByParam(queryAuditParam);
    }

    private HeroUserAudit buildEntity(Long uid, Integer authType, List<String> auditPics, List<String> auditPrivacyPics,
        String bindMobile) {
        HeroUserAudit record = new HeroUserAudit();
        record.setAuditType(authType);
        record.setImages(StringUtil.list2Str(auditPics));
        record.setPrivacyImages(StringUtil.list2Str(auditPrivacyPics));
        record.setPlatformMobile(bindMobile);
        record.setApplyUid(uid);
        record.setAuditStatus(AuditStateEnum.WAIT_AUDIT.getCode());
        record.setState(StateEnum.EFFECTIVE.getCode());
        record.setCreateBy(uid);
        record.setUpdateBy(uid);
        return record;
    }
}